using System;
using System.Collections.Generic;
using System.Resources;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Microsoft.CommerceServer.Internal;
using Microsoft.CommerceServer.Runtime;
using Microsoft.CommerceServer.Runtime.Configuration;
using RssFeedProperties;

namespace Microsoft.CommerceServer.Internal
{
    [ComImport, Guid("6432B24E-E6DA-11D2-86CF-00C04F8EC3B4"), TypeLibType((short)0x1040)]
    internal interface IPuP
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020000)]
        void Import([In, MarshalAs(UnmanagedType.BStr)] string szSiteName, [In, MarshalAs(UnmanagedType.BStr)] string szResourceName, [In, MarshalAs(UnmanagedType.BStr)] string szPath, [In] int bSilent);
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020001)]
        void Export([In, MarshalAs(UnmanagedType.BStr)] string szSiteName, [In, MarshalAs(UnmanagedType.BStr)] string szResourceName, [In, MarshalAs(UnmanagedType.BStr)] string szPath, [In] int bExportData, [In] int bSilent);
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020002)]
        void Delete([In, MarshalAs(UnmanagedType.BStr)] string szSiteName, [In, MarshalAs(UnmanagedType.BStr)] string szResourceName, [In] int bKeepData, [In] int bSilent);
        [return: MarshalAs(UnmanagedType.BStr)]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020003)]
        string CreateGroupResource([In, MarshalAs(UnmanagedType.BStr)] string szSiteName, [In, MarshalAs(UnmanagedType.BStr)] string szResourceName, [In, MarshalAs(UnmanagedType.BStr)] string szConnStr, [In, MarshalAs(UnmanagedType.BStr)] string szPath, [In] int bSilent);
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020004)]
        void DeleteGroupResource([In, MarshalAs(UnmanagedType.BStr)] string szSiteName, [In, MarshalAs(UnmanagedType.BStr)] string szResourceName, [In] int bKeepData, [In] int bSilent);
    }

    [Guid("70538141-CE64-4B81-85B6-B161F14249CF")]
    [ProgId("Commerce.RSSPup")]
    [ComVisible(true)]
    public class RssPup : IPuP
    {
        private const string RSSResourceName = "Commerce RSS";
        private const string ConnectionStringProperty = "connstr_db_RSS";
        private const string RSSResourceBaseName = "RssFeed";
        private const string RSSSchemaResource = "RssCreate";
        
        private void ExportRssData(string connectionString, string szPath)
        {
            using(SqlConnection conn = new SqlConnection(connectionString))
            using (SqlCommand getInfo = new SqlCommand())
            {
                conn.Open();
                getInfo.Connection = conn;
                getInfo.CommandType = CommandType.StoredProcedure;
				getInfo.CommandText = "[dbo].[GetAllRssFeedInfo]";

                // read all table data into a DataTable
                SqlDataReader reader = getInfo.ExecuteReader();
                DataTable dt = new DataTable("RssData");
                dt.Columns.Add("FeedInfo", typeof(System.String));
                dt.Columns.Add("UserGuid", typeof(System.Guid));
                dt.Columns.Add("FeedGuid", typeof(System.Guid));
                while (reader.Read())
                {
                    dt.Rows.Add(new object[] { reader.GetString(0), reader.GetGuid(1), reader.GetGuid(2) });
                }

                // serialize the DataTable and write to the file
                string path = szPath + "\\rssdata.xml";
                XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
                XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8);

                serializer.Serialize(writer, dt);
                writer.Close();
            }
        }

        private void ImportRssData(string connectionString, string szPath)
        {
            using(SqlConnection conn = new SqlConnection(connectionString))
            using (SqlCommand getInfo = new SqlCommand())
            {
                conn.Open();
                getInfo.Connection = conn;
                getInfo.CommandType = CommandType.StoredProcedure;
                getInfo.CommandText = "[dbo].[AddRow]";
                getInfo.Parameters.Add("@feedConfigString", SqlDbType.NText);
                getInfo.Parameters.Add("@userGuid", SqlDbType.UniqueIdentifier);
                getInfo.Parameters.Add("@feedGuid", SqlDbType.UniqueIdentifier);

                string path = szPath + "\\rssdata.xml";
                if (File.Exists(path))
                {
                    using (FileStream fileStream = new FileStream(path, FileMode.Open))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(DataTable));
                        DataTable table = (DataTable)serializer.Deserialize(fileStream);
                        foreach (DataRow row in table.Rows)
                        {
                            getInfo.Parameters["@feedConfigString"].Value = row["FeedInfo"];
                            getInfo.Parameters["@userGuid"].Value = row["UserGuid"];
                            getInfo.Parameters["@feedGuid"].Value = row["FeedGuid"];
                            getInfo.ExecuteNonQuery();
                        }
                    }
                }
            }
        }

        #region IPuP Members

        public void Import(string szSiteName, string szResourceName, string szPath, int bSilent)
        {
            if (string.IsNullOrEmpty(szSiteName))
            {
                throw new ArgumentNullException("szSiteName");
            }
            if (string.IsNullOrEmpty(szResourceName))
            {
                throw new ArgumentNullException("szResourceName");
            }
            if (!string.Equals(szResourceName, RSSResourceName, StringComparison.OrdinalIgnoreCase))
            {
                throw new NotSupportedException();
            }

            CommerceResourceCollection siteResources = new CommerceResourceCollection(szSiteName);
            CommerceResource rssResource = siteResources[RSSResourceName];
            string UncleanConnectionString = (string)rssResource[ConnectionStringProperty];
            string CleanConnectionString;
            ServerUtility.CleanSqlClientConnectionString(UncleanConnectionString, out CleanConnectionString);

            string sqlScriptContents = (string)resources.RssCreate;
            ServerUtility.ExecuteSqlScriptFromString(CleanConnectionString, sqlScriptContents);
            // import the data from rssdata.xml file if it exists
            ImportRssData(CleanConnectionString, szPath);
        }

        public void Export(string szSiteName, string szResourceName, string szPath, int bExportData, int bSilent)
        {
            if (string.IsNullOrEmpty(szSiteName))
            {
                throw new ArgumentNullException("szSiteName");
            }
            if (string.IsNullOrEmpty(szResourceName))
            {
                throw new ArgumentNullException("szResourceName");
            }
            if (!string.Equals(szResourceName, RSSResourceName, StringComparison.OrdinalIgnoreCase))
            {
                throw new NotSupportedException();
            }

            CommerceResourceCollection siteResources = new CommerceResourceCollection(szSiteName);
            CommerceResource rssResource = siteResources[RSSResourceName];
            string UncleanConnectionString = (string)rssResource[ConnectionStringProperty];
            string CleanConnectionString;
            ServerUtility.CleanSqlClientConnectionString(UncleanConnectionString, out CleanConnectionString);

            // export the data to rssdata.xml
            ExportRssData(CleanConnectionString, szPath);

            return;
        }

        public void Delete(string szSiteName, string szResourceName, int bKeepData, int bSilent)
        {
            return;
        }

        public string CreateGroupResource(string szSiteName, string szResourceName, string szConnStr, string szPath, int bSilent)
        {
            throw new NotSupportedException();
        }

        public void DeleteGroupResource(string szSiteName, string szResourceName, int bKeepData, int bSilent)
        {
            throw new NotSupportedException();
        }

        #endregion
    }
}